home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 4 / Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso / Development / Source / stuff / comp14.c next >
Text File  |  1994-05-04  |  7KB  |  273 lines

  1. /*
  2.  * Copyright (c) 1985, 1986 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * This code is derived from software contributed to Berkeley by
  6.  * James A. Woods, derived from original work by Spencer Thomas
  7.  * and Joseph Orost.
  8.  *
  9.  * Redistribution and use in source and binary forms, with or without
  10.  * modification, are permitted provided that the following conditions
  11.  * are met:
  12.  * 1. Redistributions of source code must retain the above copyright
  13.  *    notice, this list of conditions and the following disclaimer.
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in the
  16.  *    documentation and/or other materials provided with the distribution.
  17.  * 3. All advertising materials mentioning features or use of this software
  18.  *    must display the following acknowledgement:
  19.  *    This product includes software developed by the University of
  20.  *    California, Berkeley and its contributors.
  21.  * 4. Neither the name of the University nor the names of its contributors
  22.  *    may be used to endorse or promote products derived from this software
  23.  *    without specific prior written permission.
  24.  *
  25.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  26.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  29.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  30.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  31.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  32.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  33.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  34.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  35.  * SUCH DAMAGE.
  36.  */
  37.  
  38. #include "stuff.h"
  39.  
  40. typedef long int code_int;
  41. typedef long int count_int;
  42. typedef long int cmp_code_int;
  43. typedef unsigned char char_type;
  44.  
  45. enum {maxbits = 14};
  46. char_type inbuf[1024+64];
  47. char_type outbuf[1024+2048];
  48. long bytes_in;
  49. long bytes_out;
  50. count_int *htab;
  51. unsigned short *codetab;
  52.  
  53. void compress(int fdin, int fdout)
  54. {
  55. register long hp;
  56. int rpos;
  57. int outbits;
  58. int rlop;
  59. int rsize;
  60. int stcode;
  61. code_int free_ent;
  62. int boff;
  63. int n_bits;
  64. int ratio;
  65. long checkpoint;
  66. code_int extcode;
  67. union
  68. {
  69. long code;
  70. struct
  71. {
  72. char_type c;
  73. unsigned short ent;
  74. } e;
  75. } fcode;
  76. if (!htab) htab = (void *)NewPtr(18013*sizeof(count_int));
  77. if (!codetab) codetab = (void *)NewPtr(18013*sizeof(unsigned short));
  78. ratio = 0;
  79. checkpoint = 10000;
  80. extcode = (1L << (n_bits = 9))+1;
  81. stcode = 1;
  82. free_ent = 257;
  83. memset(outbuf, 0, sizeof(outbuf));
  84. bytes_out = 0; bytes_in = 0; 
  85. UpdateProgress(0);
  86. boff = outbits = 0;
  87. fcode.code = 0;
  88. memset(htab, -1, 18013*sizeof(count_int));
  89. do
  90.     {
  91.     long inOutCount = 1024;
  92.     OSErr iErr = FSRead(fdin,&inOutCount,inbuf);
  93.     if (iErr != eofErr) ChkOsErr(iErr);
  94.     rsize = inOutCount;
  95.     if ((rsize ) > 0)
  96.         {
  97.         UpdateProgress(prog_div);
  98.         crc = updcrc(crc, inbuf, rsize);
  99.         if (bytes_in == 0)
  100.             {
  101.             fcode.e.ent = inbuf[0];
  102.             rpos = 1;
  103.             }
  104.         else
  105.             rpos = 0;
  106.         rlop = 0;
  107.         do
  108.             {
  109.             if (free_ent >= extcode && fcode.e.ent < 257)
  110.                 {
  111.                 if (n_bits < maxbits)
  112.                     {
  113.                     boff = outbits = (outbits-1)+((n_bits<<3)-((outbits-boff-1+(n_bits<<3))%(n_bits<<3)));
  114.                     if (++n_bits < maxbits)
  115.                         extcode = (1L << (n_bits))+1;
  116.                     else
  117.                         extcode = (1L << (n_bits));
  118.                     }
  119.                 else
  120.                     {
  121.                     extcode = (1L << (16))+1024;
  122.                     stcode = 0;
  123.                     }
  124.                 }
  125.             if (!stcode && bytes_in >= checkpoint && fcode.e.ent < 257)
  126.                 {
  127.                 register long int rat;
  128.                 checkpoint = bytes_in + 10000;
  129.                 if (bytes_in > 0x007fffff)
  130.                     {
  131.                     rat = (bytes_out+(outbits>>3)) >> 8;
  132.                     if (rat == 0)
  133.                         rat = 0x7fffffff;
  134.                     else
  135.                         rat = bytes_in / rat;
  136.                     }
  137.                 else
  138.                     rat = (bytes_in << 8) / (bytes_out+(outbits>>3));
  139.                 if (rat >= ratio)
  140.                     ratio = (int)rat;
  141.                 else
  142.                     {
  143.                     ratio = 0;
  144.                     memset(htab, -1, 18013*sizeof(count_int));
  145.                         { 
  146.                         register char_type *p = &(outbuf)[(outbits)>>3]; 
  147.                         register long i = ((long)(256))<<((outbits)&0x7); 
  148.                         p[0] |= (char_type)(i); 
  149.                         p[1] |= (char_type)(i>>8); 
  150.                         p[2] |= (char_type)(i>>16); 
  151.                         (outbits) += (n_bits); 
  152.                         }
  153.                     boff = outbits = (outbits-1)+((n_bits<<3)-((outbits-boff-1+(n_bits<<3))%(n_bits<<3)));
  154.                     extcode = (1L << (n_bits = 9))+1;
  155.                     free_ent = 257;
  156.                     stcode = 1;
  157.                     }
  158.                 }
  159.             if (outbits >= (1024<<3))
  160.                 {
  161.                 long inOutCount = 1024;
  162.                 ChkOsErr(FSWrite(fdout,&inOutCount,outbuf));
  163.                 outbits -= (1024<<3);
  164.                 boff = -(((1024<<3)-boff)%(n_bits<<3));
  165.                 bytes_out += 1024;
  166.                 memcpy(outbuf, outbuf+1024, (outbits>>3)+1);
  167.                 memset(outbuf+(outbits>>3)+1, '\0', 1024);
  168.                 }
  169.                 {
  170.                 register int i;
  171.                 i = rsize-rlop;
  172.                 if ((code_int)i > extcode-free_ent) i = (int)(extcode-free_ent);
  173.                 if (i > ((sizeof(outbuf) - 32)*8 - outbits)/n_bits)
  174.                 i = ((sizeof(outbuf) - 32)*8 - outbits)/n_bits;
  175.                 if (!stcode && (long)i > checkpoint-bytes_in)
  176.                 i = (int)(checkpoint-bytes_in);
  177.                 rlop += i;
  178.                 bytes_in += i;
  179.                 }
  180.             goto next;
  181.             hfound: fcode.e.ent = codetab[hp];
  182.             next: if (rpos >= rlop)
  183.             goto endlop;
  184.             next2: fcode.e.c = inbuf[rpos++];
  185.                 {
  186.                 register code_int i;
  187.                 hp = (((long)(fcode.e.c)) << (14-8)) ^ (long)(fcode.e.ent);
  188.                 if ((i = htab[hp]) == fcode.code)
  189.                     goto hfound;
  190.                 if (i != -1)
  191.                     {
  192.                     long disp;
  193.                     disp = (18013 - hp)-1;
  194.                     do
  195.                         {
  196.                         if ((hp -= disp) < 0) hp += 18013;
  197.                         if ((i = htab[hp]) == fcode.code)
  198.                             goto hfound;
  199.                         }
  200.                     while (i != -1);
  201.                 }
  202.             }
  203.             {
  204.             register char_type *p = &(outbuf)[(outbits)>>3]; 
  205.             register long i = ((long)(fcode.e.ent))<<((outbits)&0x7); 
  206.             p[0] |= (char_type)(i); 
  207.             p[1] |= (char_type)(i>>8); 
  208.             p[2] |= (char_type)(i>>16); 
  209.             (outbits) += (n_bits); 
  210.             };
  211.             {
  212.             register long fc;
  213.             fc = fcode.code;
  214.             fcode.e.ent = fcode.e.c;
  215.             if (stcode)
  216.                 {
  217.                 codetab[hp] = (unsigned short)free_ent++;
  218.                 htab[hp] = fc;
  219.                 }
  220.             }
  221.         goto next;
  222.         endlop: if (fcode.e.ent >= 257 && rpos < rsize)
  223.         goto next2;
  224.         if (rpos > rlop)
  225.             {
  226.             bytes_in += rpos-rlop;
  227.             rlop = rpos;
  228.             }
  229.         }
  230.     while (rlop < rsize);
  231.     }
  232. }
  233. while (rsize > 0);
  234. if (bytes_in > 0)
  235.     { 
  236.     register char_type *p = &(outbuf)[(outbits)>>3]; 
  237.     register long i = ((long)(fcode.e.ent))<<((outbits)&0x7); 
  238.     p[0] |= (char_type)(i); 
  239.     p[1] |= (char_type)(i>>8); 
  240.     p[2] |= (char_type)(i>>16); 
  241.     (outbits) += (n_bits); 
  242.     }
  243.     {
  244.     OSErr iErr;
  245.     long inOutCount = (outbits+7)>>3;
  246.     ChkOsErr(FSWrite(fdout,&inOutCount,outbuf));
  247.     bytes_out += (outbits+7)>>3;
  248.     }
  249. UpdateProgress(0);
  250. }
  251.  
  252. void copy(int fdin, int fdout)
  253. {
  254. long inOutCount;
  255. OSErr iErr;
  256. UpdateProgress(0);
  257. bytes_out = 0;
  258. do
  259.     {
  260.     inOutCount = 32768;
  261.     iErr = FSRead(fdin,&inOutCount,codetab);
  262.     if (iErr != eofErr) ChkOsErr(iErr);
  263.     if (inOutCount > 0)
  264.         {
  265.         ChkOsErr(FSWrite(fdout,&inOutCount,codetab));
  266.         bytes_out += inOutCount;
  267.         UpdateProgress(prog_div<<5);
  268.         }
  269.     }
  270. while (inOutCount > 0);
  271. UpdateProgress(0);
  272. }
  273.